<!DOCTYPE html>
<html>

<head>
  <title>Introducing Command Mode</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/blog/introducing-command-mode/" />
  <meta property="og:title" content="Introducing Command Mode" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/blog/introducing-command-mode/">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="post">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="active">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="post-page grid-wrapper">
  <div class="width-8-12 width-12-12-m doc-content">
    <div class="grid-wrapper">
      <div class="width-12-12">
        <p>
          <a href="/blog"><i class="fas fa-angle-left"></i> Back to all posts</a>
        </p>
      </div>
      <div class="width-12-12">
        <div class="post-date">
          May 05, 2020 
          
            <span class="tags"><a href="/blog/tag/development-tips">#development-tips</a></span>
          
        </div>
        <h1 class="post-title">Introducing Command Mode</h1>
        <div class="grid-wrapper">
          <div class="width-8-12 width-12-12-m byline-wrapper">
            
            
              <img class="headshot" src="https://www.gravatar.com/avatar/9ac47c2c99739d75d633f4d9b73eef35">
            
            <p class="byline">By Max Rydahl Andersen</p>
          </div>
          <div class="width-12-12">
              <div class="paragraph">
<p>Ever wanted to use Quarkus awesome API&#8217;s and full feature set from a command line application ?</p>
</div>
<div class="paragraph">
<p>Did you need to run a scheduled batch job now and then and not wanting to embed it into your main Quarkus built service ?</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="https://i.imgflip.com/3xwzsh.jpg" alt="3xwzsh"></span></p>
</div>
<div class="paragraph">
<p>Quarkus has thus far been used to write applications that runs via an endpoint i.e. long running webserver via http or short-lived function in a serverless environment.</p>
</div>
<div class="paragraph">
<p>In Quarkus 1.4 command mode lets you write apps that run without an endpoint and optionally exits immediately.</p>
</div>
<div class="paragraph">
<p>This enables you to use Quarkus for writing a whole new style of applications - think command line clients (CLI), batch scripts, console apps, etc.</p>
</div>
<div class="sect1">
<h2 id="how-to-use-it"><a class="anchor" href="#how-to-use-it"></a>How to use it</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Below is a simple <code>GreetingMain</code> class which uses the traditional <code>GreetingService</code> from all our quickstarts.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.runtime.annotations.QuarkusMain;

@QuarkusMain    <i class="conum" data-value="1"></i><b>(1)</b>
public class GreetingMain implements QuarkusApplication {
  @Inject <i class="conum" data-value="2"></i><b>(2)</b>
  GreetingService service;

  @Override
  public int run(String... args) throws Exception {   <i class="conum" data-value="3"></i><b>(3)</b>

    if (args.length&gt;0) {
      System.out.println(service.greeting(arg[0]));
    } else {
      System.out.println(service.greeting(""));
    }

    return 0;
 }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The <code>@QuarkusMain</code> annotation tells Quarkus that this is the main entry point.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>The <code>run</code> method is invoked once Quarkus starts, and the application stops when it finishes. If you would like to access request scoped beans you can annotate the <code>run</code> method with <code>@ActivateRequestContext</code>. This is useful to write or reuse your existing business logic using i.e. Hibernate Panache Entity beans query methods.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>You can add this to a <code>GreetingMain.java</code> and compile to a .jar or to full native (using <code>mvnw package -Dnative</code>) and when run you get something like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs"> ./target/getting-started-command-mode-1.0-SNAPSHOT-runner commando
__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,&lt; / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) getting-started-command-mode 1.0-SNAPSHOT (powered by Quarkus 999-SNAPSHOT) started in 0.005s.
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) Profile prod activated.
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) Installed features: [cdi]
hello commando
2020-04-25 00:14:38,999 INFO  [io.quarkus] (main) getting-started-command-mode stopped in 0.000s</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="clean-output"><a class="anchor" href="#clean-output"></a>Clean output</h3>
<div class="paragraph">
<p>When working with a cli the default console log output can be verbose. For now the best way to turn that off is by setting the following properties:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">quarkus.log.level=SEVERE
quarkus.hibernate-orm.log.sql=false
quarkus.banner.enabled=false</code></pre>
</div>
</div>
<div class="paragraph">
<p>These could be set in a custom profile called <code>cli</code> by adding a <code>%cli.</code> prefix.</p>
</div>
<div class="paragraph">
<p>This has some issues and possible solution are being discussed in issue <a href="https://github.com/quarkusio/quarkus/issues/8871">#8871</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="development-mode"><a class="anchor" href="#development-mode"></a>Development mode</h3>
<div class="paragraph">
<p>Command mode works with <code>quarkus:dev</code> aka. dev-mode.</p>
</div>
<div class="paragraph">
<p>When you run with <code>mvn quarkus:dev</code> you can add <code>-Dquarkus.args=yourvalue</code> as arguments you want to pass into the command line.</p>
</div>
<div class="paragraph">
<p><code>quarkusargs</code> will be split on whitespace and honors escaped quotes to. Thus with <code>mvn quarkus:dev -Dquarkus.args="foo bar \"baz qux\""</code> the app will start and after end look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">foo
bar
baz qux
Quarkus application exited with code 0
Press Enter to restart or Ctrl + C to quit</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can now Press Enter multiple times to force a rerun and if you edited source code Press Enter will trigger build and then restart with no real overhead.</p>
</div>
</div>
<div class="sect2">
<h3 id="main-methods"><a class="anchor" href="#main-methods"></a>Main methods</h3>
<div class="paragraph">
<p>As part of adding command mode via a <code>@QuarkusMain</code> annotated class you can now have your own <code>static void main()</code> method. Below snippet is the minimum to run Quarkus from a main method.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">static void main(String ...args) {
    Quarkus.run(args);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>To use it with the above <code>@QuarksMain</code> class would look something like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">static void main(String ...args) {
    Quarkus.run(GreetingMain.class, args);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>That is all. This allows you to not only customize start/stop of your Quarks app and what many asked for: ability to launch/debug a Quarkus app directly from an IDE.</p>
</div>
<div class="paragraph">
<p>You can see a fully working example of these classes in the <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/development/getting-started-command-mode">command-mode quickstart</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="minimal-cli-app"><a class="anchor" href="#minimal-cli-app"></a>Minimal CLI App</h3>
<div class="paragraph">
<p>It is worth noticing that your cli app can still be serving out an endpoint - in fact, in the default app as we just made the rest endpoint is still starting and running. You just don&#8217;t notice it. Quarkus is that fast.</p>
</div>
<div class="paragraph">
<p>In case you truly want a minimal extension you remove the <code>quarkus-resteasy</code> extension in your <code>pom.xml</code> and put <code>arc</code> instead.</p>
</div>
<div class="paragraph">
<p>Then nothing else than your Quarkus main class will be run.</p>
</div>
</div>
<div class="sect2">
<h3 id="what-is-next"><a class="anchor" href="#what-is-next"></a>What is next ?</h3>
<div class="paragraph">
<p>You tell us! What would you like to do with a command app with Quarkus ?</p>
</div>
<div class="paragraph">
<p>For now we are enjoying writing CLI&#8217;s but how many others will join us!</p>
</div>
<div class="paragraph">
<p>Let us know of your ideas at <a href="https://github.com/quarkusio/quarkus/issues" class="bare">https://github.com/quarkusio/quarkus/issues</a>.</p>
</div>
</div>
</div>
</div>
              
          </div>
          <div class="width-12-12"><div class="share-page">
  <a class="share-linkedin" href="https://www.linkedin.com/shareArticle?mini=true&url=https://quarkus.io/blog/introducing-command-mode/&title=Introducing Command Mode" rel="nofollow" target="_blank" title="Share on LinkedIn">
    <img src="/assets/images/share-page/icons_social-linkedin.png"/>
  </a>
  <a class="share-twitter" href="https://twitter.com/intent/tweet?text=Introducing Command Mode&url=https://quarkus.io/blog/introducing-command-mode/&via=quarkusio&related=quarkusio" rel="nofollow" target="_blank" title="Share on Twitter">
    <img src="/assets/images/share-page/icons_social-twitter.png"/>
  </a>
  <a class="share-facebook" href="https://facebook.com/sharer.php?u=https://quarkus.io/blog/introducing-command-mode/" rel="nofollow" target="_blank" title="Share on Facebook">
    <img src="/assets/images/share-page/icons_social-facebook.png"/>
  </a>
  <a class="share-reddit" href="http://www.reddit.com/submit?url=https://quarkus.io/blog/introducing-command-mode/" onclick="window.open(this.href, 'pop-up', 'left=20,top=20,width=900,height=500,toolbar=1,resizable=0'); return false;" title="Share on Reddit" >
    <img src="/assets/images/share-page/icons_social-reddit.png"/>
  </a>
  <a class="share-email" href="mailto:?subject=Introducing Command Mode&amp;body=Introducing Command Mode https://quarkus.io/blog/introducing-command-mode/" title="Share via Email" >
    <img src="/assets/images/share-page/icons_social-email.png"/>
  </a>
</div>
</div>
        </div>
      </div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
